package com.xiaomage.sharedpreferences_contentprovider

import android.content.Context
import android.content.SharedPreferences
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.MAINSPNAME
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_BOOLEAN
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_FLOAT
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_INT
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_LONG
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_STRING
import com.xiaomage.sharedpreferences_contentprovider.ConstantUtil.TYPE_STRING_SET
import java.lang.ref.SoftReference
import java.util.*
import kotlin.collections.HashMap

/**
 * Created by Administrator on 2018/4/1 0001.
 */
object SPHelperImple {
    var cacheMap:SoftReference<MutableMap<String?,Any?>>?=null
    fun getSP(context: Context?):SharedPreferences?{
        if(context==null) return null
        return context.getSharedPreferences(MAINSPNAME,Context.MODE_PRIVATE)
    }
    fun getALL(context: Context?):Map<String,*>?{
        val sp= getSP(context)
        return sp?.all
    }

    //判断是否包含
    fun contains(context: Context?,name:String?):Boolean{
        val sp= getSP(context) ?: return false
        return sp.contains(name)
    }

    private fun getCacheValue(name: String?):Any?{
        if(cacheMap==null) return null
        val map= cacheMap?.get() ?: return null
        return map[name]
    }
    private fun getString(context: Context?,name: String?,defaultValue: String?):String?{
        val sp= getSP(context)?:return defaultValue
        return sp.getString(name,defaultValue)
    }

    private fun getBoolean(context: Context?,name: String?,defaultValue: Boolean):Boolean?{
        val sp= getSP(context)?:return defaultValue
        return sp.getBoolean(name,defaultValue)
    }

    private fun getInt(context: Context?,name:String?,defaultValue: Int):Int{
        val sp= getSP(context)?:return defaultValue
        return sp.getInt(name,defaultValue)
    }
    private fun getLong(context: Context?,name: String?,defaultValue: Long):Long{
        val sp= getSP(context)?:return defaultValue
        return sp.getLong(name,defaultValue)
    }
    private fun getFloat(context: Context?,name: String?,defaultValue: Float):Float{
        val sp= getSP(context)?: return  defaultValue
        return sp.getFloat(name ,defaultValue)
    }
    private fun get_impl(context: Context?,name: String?,type:String?):Any?{
        if(!contains(context,name)){
            return null
        }else{
            if(type.equals(TYPE_STRING,ignoreCase = true)){
                return getString(context,name,null)
            }else if(type.equals(TYPE_BOOLEAN,ignoreCase = true)){
                return getBoolean(context,name,false)
            }else if(type.equals(TYPE_INT,ignoreCase = true)){
                return getInt(context,name,0)
            }else if(type.equals(TYPE_LONG,ignoreCase = true)){
                return getLong(context,name,0)
            }else if(type.equals(TYPE_FLOAT,ignoreCase = true)){
                return getFloat(context ,name,0f)
            }else if(type.equals(TYPE_STRING_SET,ignoreCase = true)){
                return getString(context,name,null)
            }
            return null
        }
    }
    private fun saveValueToCache(name: String?,value:Any?){
        var map:MutableMap<String?,Any?>?
        if(cacheMap==null){
            map=HashMap()
            cacheMap=SoftReference(map)
        }else{
            map= cacheMap?.get()
            if(map==null){
                map=HashMap()
                cacheMap=SoftReference(map)
            }
        }
        map?.put(name,value)
    }

    fun get(context: Context?,name: String?,type:String?):String{
        var value= getCacheValue(name)
        if(value!=null){
            return value.toString()
        }else{
            value= get_impl(context,name,type)
            saveValueToCache(name,value)
            return ""+value
        }
    }

    @Synchronized
    fun <T> save(context: Context?,name: String?,t:T){
        val sp= getSP(context)?:return
        if(t == getCacheValue(name)) return
        val editor=sp.edit()
        when(t){
            is Boolean->{
                editor.putBoolean(name,t)
            }
            is String->{
                editor.putString(name,t)
            }
            is Int->{
                editor.putInt(name,t)
            }
            is Long->{
                editor.putLong(name,t)
            }
            is Float->{
                editor.putFloat(name,t)
            }
        }
        editor.commit()
        saveValueToCache(name,t)
    }

    private fun cleanCacheValue(){
        if(cacheMap!=null){
            val map= cacheMap?.get()
            map?.clear()
        }
    }
    fun clear(context: Context?){
        val sp= getSP(context)
        val editor=sp?.edit()
        editor?.clear()
        editor?.commit()
        cleanCacheValue()
    }

    fun remove(context: Context?,key:String?){
        val sp= getSP(context)
        val editor=sp?.edit()
        editor?.remove(key)
        editor?.commit()
    }


}